package com.gxa.jjty.admin.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 配置Redis操作数据(key/value)的时候运用序列化格式
 * @author asus
 */
@Configuration
public class RedisConfig {

    /**
     * RedisTemplate<K,V>操作对象Redis的主体对象，序列化的配置要在RedisTemplate中体现
     * K：key的泛型类型，用String表示
     * V：value的泛型类型，为了把5种类型(String/Class/List/Set)都概括，所以要用Object
     * @param factory RedisConnextionFactory:spring从当前配置中加载pool连接池配置和Redis基础连接配置项生成的factory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    // 实例化一个RedisTemplate(操作redis中不同数据类型的CRUD)
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
    // 给template配置一个factory,指定连接
        redisTemplate.setConnectionFactory(factory);
    //配置序列化器: 针对String和hash采用何种序列化方式(java把数据传给redis时使用
        // 何种格式: jdk/string/jackson)
        // Jackson序列化器，把user对象 生成{id:1,name:zhang,age:10}
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //ObjectMapper 是jackson 转换json格式的核心类型
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //String序列化器 name->"baiduhot"
        /*在java包中创建Controller控制器
        PS：注意，这里放置的位置是包的根目录，目的是为了控制器的包扫描
        MainController类中的代码如下(@SpringBootApplication拥有扫描功能，扫描此目录下的所有类，所
        以官方建议放置在根目录下)：*/
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();


    // key采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
    // hash的key也采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
    // value序列化方式采用jackson
    // user[name=张三] -> {"user":{"name":"张三"}}
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    // hash的value序列化方式采用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
